package model;
import java.util.Map;


public class LCAWeightingModel {
	private Collection c;
	private String query[];
	private String[] topNDocs;

	public LCAWeightingModel(Collection c, String query, int N) {
		this.c = c;
		this.query = query.split("\\s");
		this.topNDocs = c.topNDocs(N);
	}

	/**
	 * Calculate the aggregated term frequency for a single term
	 * 
	 * @param concept
	 * @param term
	 * @return
	 */
	private int aggregatedTF(String concept, String term) {
		//System.out.println("The concept is: "+concept+"  The term is: "+term);
		int conceptFrequency = 0, queryTermFrequency = 0, aggregatedFrequency = 0;
		for (String docID : topNDocs) {
			Map<String, Integer> doc = c.collection.get(docID);
			conceptFrequency = doc.get(concept) == null ? 0 : doc.get(concept);
			queryTermFrequency += doc.get(term) == null ? 0 : doc.get(term);
			/*System.out.println(concept + "(" + conceptFrequency + ")" + ":"
					+ term + "(" + queryTermFrequency + ")");*/
			aggregatedFrequency += conceptFrequency * queryTermFrequency;
		}
	//	System.out.println("The aggregatedFrequency is: "+aggregatedFrequency);
		return aggregatedFrequency;
	}

	/**
	 * Calculate the inverted document frequency for a given string
	 * 
	 * @param string
	 * @return
	 */
	private double idf(String string) {
		
		//System.out.println("String is: "+string);
		int df = 0;
		double idf = 0.0;
		for (String docID : topNDocs) {
			if (c.collection.get(docID).get(string) != null) {
				//System.out.println("Find in the "+docID);
				df++;
			}
		}
		
		if(df==0)
		{
			idf = 1;
		}
		else
		{
			idf = Math.log10((double) topNDocs.length / df) / 5;
			if (idf < 1) {
				idf = 1;
			}
		}
		
		
		//System.out.println("idf is "+idf);
		return idf;
	}

	/**
	 * Calculate the similarity between a concept and the given query
	 * 
	 * @param concept
	 * @return
	 */
	public double similarity(String concept) {
		double conceptSimilarity = 1;
		
		for (String term : query) {
			
			int aggregatedTFResult = aggregatedTF(concept, term);
			
			if(aggregatedTFResult == 0)
			{
				aggregatedTFResult = 1;
						
			}
			
			conceptSimilarity *= Math.pow(
					(0.1 + Math.log10(aggregatedTFResult))
							* idf(concept) / Math.log10(topNDocs.length),
					idf(term));
			System.out.println(concept + ",co-occur tf:" +aggregatedTFResult +",doc count"+idf(concept) +"::"+topNDocs.length);
		}
		return conceptSimilarity;
	}
}
